package xcu.lxj.nettychat.chat.dao;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xcu.lxj.nettychat.chat.domain.entity.Message;
import xcu.lxj.nettychat.chat.domain.enums.MessageStatusEnum;
import xcu.lxj.nettychat.chat.mapper.MessageMapper;
import xcu.lxj.nettychat.common.domain.vo.request.CursorPageBaseReq;
import xcu.lxj.nettychat.common.domain.vo.response.CursorPageBaseResp;
import xcu.lxj.nettychat.common.utils.CursorUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author XinJian Lei
 * @Date 2024/9/26 20:19
 * @Version 1.0
 */
@Service
public class MessageDao extends ServiceImpl<MessageMapper, Message> {


    public CursorPageBaseResp<Message> getCursorPage(Long roomId, CursorPageBaseReq request, Long lastMsgId) {
        return CursorUtils.getCursorPageByMysql(this, request, wrapper -> {
            wrapper.eq(Message::getRoomId, roomId);
            wrapper.eq(Message::getStatus, MessageStatusEnum.NORMAL.getStatus());
            wrapper.le(Objects.nonNull(lastMsgId), Message::getId, lastMsgId);
        }, Message::getId);
    }

    /**
     * 乐观更新消息类型
     */
    public boolean riseOptimistic(Long id, Integer oldType, Integer newType) {
        return lambdaUpdate()
                .eq(Message::getId, id)
                .eq(Message::getType, oldType)
                .set(Message::getType, newType)
                .update();
    }

    /**
     * 获取两个消息间隔的个数
     * @param roomId
     * @param fromId
     * @param toId
     * @return
     */
    public Integer getGapCount(Long roomId, Long fromId, Long toId) {
        return Math.toIntExact(lambdaQuery()
                .eq(Message::getRoomId, roomId)
                .gt(Message::getId, fromId)
                .le(Message::getId, toId)
                .count());
    }

    /**
     * 让uid对应的消息失效 ， 用于拉黑 和删除用户
     * @param uid 用户id
     */
    public void invalidByUid(Long uid) {
        lambdaUpdate()
                .eq(Message::getFromUid, uid)
                .set(Message::getStatus, MessageStatusEnum.DELETE.getStatus())
                .update();
    }
    /**
     * 获取未赌的消息数
     * @param roomId 房间id
     * @param readTime 用户最后阅读的时间
     * @return
     */
    public Integer getUnReadCount(Long roomId, Date readTime) {
        return Math.toIntExact(lambdaQuery()
                .eq(Message::getRoomId, roomId)
                .gt(Objects.nonNull(readTime), Message::getCreateTime, readTime)
                .count());
    }

    /**
     * 根据房间ID逻辑删除消息
     *
     * @param roomId  房间ID
     * @param uidList 群成员列表
     * @return 是否删除成功
     */
    public Boolean removeByRoomId(Long roomId, List<Long> uidList) {
        if (CollectionUtil.isNotEmpty(uidList)) {
            LambdaUpdateWrapper<Message> wrapper = new UpdateWrapper<Message>().lambda()
                    .eq(Message::getRoomId, roomId)
                    .in(Message::getFromUid, uidList)
                    .set(Message::getStatus, MessageStatusEnum.DELETE.getStatus());
            return this.update(wrapper);
        }
        return false;
    }




}
